package com.dongzili.demo.common.config.es;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import org.dromara.easyes.annotation.IndexName;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

@Order(11)
@Configuration
@Slf4j
@AutoConfigureAfter(SpringUtil.class)
public class EsMapperConfig {

    private static final List<String> BASE_PACKAGES = Arrays.asList(
            "com.dongzili.demo.customer.model"
            ,"com.dongzili.demo.customer.pgsql.model"
    );
    // 根据类名获取 bean name
    private String getBeanName(String className) {

        int index = className.lastIndexOf(".");
        String simpleClassName = index != -1 ? className.substring(index + 1) : className;

        char firstChar = simpleClassName.charAt(0);
        if (firstChar >= 'A' && firstChar <= 'Z') {
            firstChar -= 'A' - 'a';
        }
        return firstChar + simpleClassName.substring(1);
    }

    @PostConstruct
    public void setup() {
        for (String packageName : BASE_PACKAGES){
            if(!StringUtils.hasText(packageName)){
                continue;
            }
            // 扫描数据库实体，根据实体创建对应 mapper、service
            Set<Class<?>> entityClassSet = ClassUtil.scanPackage(packageName);
            if (entityClassSet.isEmpty()) {
                continue;
            }
            for (Class<?> entityClass : entityClassSet) {
                // 只创建带有 MapAndService 注解的实体
                IndexName indexName = entityClass.getAnnotation(IndexName.class);
                if (indexName == null) {
                    continue;
                }
                String mapperClassName = packageName + ".mapper" + "." + entityClass.getSimpleName() + "AutoEsMapper";
                /* 创建 mapper */
                Class<?> mapperClass = new ByteBuddy()
                        .makeInterface(TypeDescription.Generic.Builder.parameterizedType(BaseEsMapper.class, entityClass).build())
                        .name(mapperClassName)
                        .annotateType(AnnotationDescription.Builder.ofType(Repository.class).build())
                        .make()
                        .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                        .getLoaded();
//                EsMapperFactoryBean<?> factoryBean = SpringUtil.getBean(EsMapperFactoryBean.class);
//                factoryBean.setMapperInterface(mapperClass);
                EsMapperFactoryBean<?> factoryBean = SpringUtil.getBean(EsMapperFactoryBean.class);//new EsMapperFactoryBean<>(mapperClass);

                try {
                    SpringUtil.registerBean(getBeanName(mapperClassName), factoryBean.getObject(mapperClass));
                    log.info("自动注册 easy-es mapper bean -> 名称:{}, 类名：{}", getBeanName(mapperClassName), mapperClassName);
                } catch (Exception e) {
                    log.error("自动注册 easy-es mapper bean 失败", e);
                    e.printStackTrace();
                }
            }
        }
    }

}
